package ldkxingzhe.androidmedia.chapter2;

import android.content.ContentValues;
import android.content.res.Configuration;
import android.hardware.Camera;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.RelativeLayout;

import java.io.IOException;
import java.io.OutputStream;
import java.util.List;

import ldkxingzhe.androidmedia.R;

/**
 * Created by xingzhe on 15/10/27.
 */
public class SnapShotActivity extends AppCompatActivity implements SurfaceHolder.Callback, Camera.PictureCallback, View.OnClickListener{
    private static final String TAG = SnapShotActivity.class.getSimpleName();

    // MARK: UI relative elements
    private SurfaceView mSurfaceView;
    private SurfaceHolder mSurfaceHolder;

    // MARK: another object
    private Camera mCamera;

    // MARK: Constants
    private  int LARGEST_WIDTH = 200;
    private  int LARGEST_HEIGHT = 200;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.chapter2_activity_snap_shot);
        mSurfaceView = (SurfaceView)findViewById(R.id.chapter2_surface_view);
        mSurfaceHolder = mSurfaceView.getHolder();

        // the draw buffers are maintained extenal to the Surface itself,
        // this is required by Camera class
        mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        mSurfaceHolder.addCallback(this);

        mSurfaceView.setFocusable(true);
        mSurfaceView.setFocusableInTouchMode(true);
        mSurfaceView.setClickable(true);
        mSurfaceView.setOnClickListener(this);
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        Log.d(TAG, "surfaceCreated");
        mCamera = getCameraInstance();
        if(mCamera == null){
            return;
        }
        try{

            Camera.Parameters parameters = mCamera.getParameters();
            if(getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE){
//                parameters.set("orientation", "portait");
                mCamera.setDisplayOrientation(90);
                parameters.setRotation(90);
            }else{
//                parameters.set("oritentation", "landscape");
                mCamera.setDisplayOrientation(0);
                parameters.setRotation(0);
            }

            // MARK: find the best size
            int bestWidth = 0, bestHeight = 0;
            LARGEST_WIDTH = mSurfaceView.getWidth();
            LARGEST_HEIGHT = mSurfaceView.getHeight();
            Log.v(TAG,"LargestWidth is " + LARGEST_WIDTH + ", LargestHeight is " + LARGEST_HEIGHT);
            List<Camera.Size> sizeList = parameters.getSupportedPreviewSizes();
            for(Camera.Size tmpSize : sizeList){
                Log.v(TAG,"tmpSize: width is " + tmpSize.width + ", height is " + tmpSize.height);
                if(tmpSize.width > bestWidth && tmpSize.width < LARGEST_WIDTH
                        && tmpSize.height > bestHeight && tmpSize.height < LARGEST_HEIGHT){
                    bestWidth = tmpSize.width;
                    bestHeight = tmpSize.height;
                }
            }
            Log.v(TAG,"bestWidth is " + bestWidth + ", bestHeight is " + bestHeight);
            if(bestWidth != 0 && bestHeight != 0){
                parameters.setPreviewSize(bestWidth, bestHeight);
                mSurfaceView.setLayoutParams(new RelativeLayout.LayoutParams(bestWidth, bestHeight));
            }

            mCamera.setParameters(parameters);
            mCamera.setPreviewDisplay(mSurfaceHolder);
        } catch (IOException e) {
            Log.e(TAG,"" + e.getMessage(), e);
            mCamera.release();
        }
        mCamera.startPreview();
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        Log.v(TAG,"surfaceChanged");
        mCamera.startPreview();
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        Log.d(TAG,"surfaceDestroyed");
        if(mCamera != null){
            mCamera.stopPreview();
            mCamera.release();
        }
    }

    public static Camera getCameraInstance(){
        Camera c = null;
        try{
            c = Camera.open();
        }catch (Exception e){
            Log.e(TAG,"" + e.getMessage(), e);
        }
        return c;
    }

    @Override
    public void onPictureTaken(byte[] data, Camera camera) {
        Log.v(TAG,"onPictureTaken");
        Uri imageFileUri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, new ContentValues());
        OutputStream imageFileOS = null;
        try{
            imageFileOS = getContentResolver().openOutputStream(imageFileUri);
            imageFileOS.write(data);
            imageFileOS.flush();
        } catch (Exception e) {
            Log.e(TAG,e.getMessage(),e);
        } finally {
            if(imageFileOS != null){
                try {
                    imageFileOS.close();
                } catch (IOException e) {
                    Log.e(TAG, e.getMessage(),e);
                }
            }
        }

        camera.startPreview();
        Log.v(TAG,"path is " + imageFileUri.getPath());
    }

    @Override
    public void onClick(View v) {
        if(mCamera != null){
            mCamera.takePicture(null,null,this);
        }
    }
}
